﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ForrajeriaDB; //ESTE USING VA EN TODOS LOS ELEMENTOS DE ESTA CAPA
using System.Data;
using System.Data.SqlClient;
namespace ForrajeriaDAL
{
    public class ForrajeDAL : AccesoDAL, InterfazDAL<ForrajeMO>
    {

        #region VARIABLES PARA STORED QUE MANEJA EL OBJETO DE DAL

        private static string insert = "Forraje_INSERT";
        private static string delete = "Forraje_DELETE";
        private static string update = "Forraje_UPDATE";
        private static string all = "Forraje_GetALL";
        private static string detalle = "AnimalXForraje_getbyForraje";
        private static string forrajexId = "Forraje_getByID";

        #endregion

        private SqlCommand cmd; //var de comando sql

        #region "Singleton"

        private static ForrajeDAL instance;

        private ForrajeDAL()
            : base()
        {

        }


        public static ForrajeDAL Instance
        {
            get
            {
                if (instance == null)
                {
                    instance = new ForrajeDAL();
                }
                return instance;
            }
        }

        #endregion

        #region Interfaz

        public List<ForrajeMO> GetAll()
        {
            SqlDataReader reader = null;
            List<ForrajeMO> lista = new List<ForrajeMO>();
            try
            {

                cmd = new SqlCommand(all, getConexion());
                cmd.CommandType = CommandType.StoredProcedure;
                opencon(); // abre coneccion 
                reader = cmd.ExecuteReader();
                while (reader.Read())
                {

                    ForrajeMO aux = new ForrajeMO();

                    //**************************************Formacion del objeto aux ******************************************************************
                    aux.CodigoEdad = int.Parse(reader["codigoEdad"].ToString());
                    aux.CodigoForraje = int.Parse(reader["codigoForraje"].ToString());
                    if (reader["descripcion"].ToString() != null)
                        aux.Descripcion = reader["descripcion"].ToString();
                    else
                        aux.Descripcion = "";

                    aux.NombreForraje = reader["nombreForraje"].ToString();
                    aux.StockActual = double.Parse(reader["stockActual"].ToString());

                    if (reader["stockMinimo"].ToString() == "")
                        aux.StockMinimo = 0;
                    else
                        aux.StockMinimo = double.Parse(reader["stockMinimo"].ToString());
                    if (reader["stockMaximo"].ToString() == "")
                        aux.StockMaximo = null;
                    else
                        aux.StockMaximo = double.Parse(reader["stockMaximo"].ToString());

                    if (reader["peso"].ToString() == "")
                        aux.Peso = null;
                    else
                        aux.Peso = double.Parse(reader["peso"].ToString());

                    aux.CodigoMarca = int.Parse(reader["CodigoMarca"].ToString());

                    if (reader["estado"].ToString() != null)
                        aux.Estado = reader["estado"].ToString();
                    else
                        aux.Estado = "";
                    if (reader["precioXKilo"].ToString() != "")
                        aux.PrecioXKilo = double.Parse(reader["precioXKilo"].ToString());
                    else
                        aux.PrecioXKilo = 0;

                    //********************************** fin Formacion objeto aux **********************************************************************

                    lista.Add(aux);
                    aux = null;
                }
                return lista;
            }
            catch (Exception ex)
            {
                throw ex; //en caso que no pueda leer desde la base de datos tira el hacia la siguiente capa 
            }
           finally //finalmente cierro el reader que use para traer la consulta esto es importante ya que por alguna razon podria quedar abierto generando una conexion sin uso en la bd que estaria todo el tiempo abierta
            {
                closeReader(reader); //cierro el reader
                closecon();// cierra conexion

            }
        }

        public void Adicionar(ForrajeMO item)
        {
            item.CodigoForraje = getCodigoInsert("Forraje", "CodigoForraje"); //obtengo el codigo de insercion

            try
            {
                cmd = new SqlCommand(insert, getConexion());
                cmd.CommandType = CommandType.StoredProcedure;


                cmd.Parameters.Add(new SqlParameter("@codigoForraje",  item.CodigoForraje));
                cmd.Parameters.Add(new SqlParameter("@descripcion", item.Descripcion));
                cmd.Parameters.Add(new SqlParameter("@nombreForraje",  item.NombreForraje));

                cmd.Parameters.Add(new SqlParameter("@stockActual", item.StockActual));
                cmd.Parameters.Add(new SqlParameter("@stockMinimo", item.StockMinimo));


                cmd.Parameters.Add(new SqlParameter("@stockMaximo",  item.StockMaximo));
                cmd.Parameters.Add(new SqlParameter("@codigoEdad",  item.CodigoEdad));
                cmd.Parameters.Add(new SqlParameter("@peso",  item.Peso));
                cmd.Parameters.Add(new SqlParameter("@estado", item.Estado));
                cmd.Parameters.Add(new SqlParameter("@codigoMarca", item.CodigoMarca));
                cmd.Parameters.Add(new SqlParameter("@precioXKilo",  item.PrecioXKilo));


                opencon(); //abro conexion
                cmd.ExecuteNonQuery();
                closecon(); //cierra conexion

            }
            catch (SqlException ex)
            {
                closecon();
                throw ex;
            }

        }

        public void Eliminar(ForrajeMO item)
        {
            try
            {
                cmd = new SqlCommand(delete, getConexion());
                cmd.CommandType = CommandType.StoredProcedure;
                cmd.Parameters.Add(new SqlParameter("@codigoForraje", item.CodigoForraje));

                opencon();
                cmd.ExecuteNonQuery();
                closecon();
            }

            catch (SqlException ex)
            {
                closecon();
                throw ex;

            }
        }

        public void Actualizar(ForrajeMO nuevoItem, ForrajeMO origItem)
        {
            try
            {
                cmd = new SqlCommand(update, getConexion());
                cmd.CommandType = CommandType.StoredProcedure;



                cmd.Parameters.Add(new SqlParameter("@codigoForraje",origItem.CodigoForraje));
                cmd.Parameters.Add(new SqlParameter("@descripcion", nuevoItem.Descripcion));
                cmd.Parameters.Add(new SqlParameter("@nombreForraje", nuevoItem.NombreForraje));

                cmd.Parameters.Add(new SqlParameter("@stockActual", nuevoItem.StockActual));
                cmd.Parameters.Add(new SqlParameter("@stockMinimo", nuevoItem.StockMinimo));


                cmd.Parameters.Add(new SqlParameter("@stockMaximo",  nuevoItem.StockMaximo));
                cmd.Parameters.Add(new SqlParameter("@codigoEdad", nuevoItem.CodigoEdad));
                cmd.Parameters.Add(new SqlParameter("@peso", nuevoItem.Peso));
                cmd.Parameters.Add(new SqlParameter("@estado", nuevoItem.Estado));
                cmd.Parameters.Add(new SqlParameter("@codigoMarca", nuevoItem.CodigoMarca));
                cmd.Parameters.Add(new SqlParameter("@precioXKilo",  nuevoItem.PrecioXKilo));

                opencon();
                cmd.ExecuteNonQuery();
                closecon();

            }
            catch (SqlException ex)
            {
                closecon();
                throw ex;
            }
        }

        #endregion
        public DataTable buscarProductos(string nombre, int edad, int marca)
        {
            DataTable dt = new DataTable();

            SqlDataAdapter da = null;


            try
            {
                cmd = new SqlCommand("Producto_Buscar", getConexion());

                cmd.CommandType = CommandType.StoredProcedure;
                cmd.Parameters.Add(new SqlParameter("@nombre",  nombre));
                cmd.Parameters.Add(new SqlParameter("@marca",  marca));
                cmd.Parameters.Add(new SqlParameter("@edad",  edad));

                opencon();
                da = new SqlDataAdapter(cmd);


                da.Fill(dt);

            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                closecon();

            }

            return dt;



        }
        public ForrajeMO getbyID(int codigo)
        {
            cmd = new SqlCommand(forrajexId, getConexion());
            cmd.CommandType = CommandType.StoredProcedure;

            cmd.Parameters.Add(new SqlParameter("@id",  codigo));
            SqlDataReader reader = null;
            try
            {
                opencon();
                reader = cmd.ExecuteReader();
                ForrajeMO aux = new ForrajeMO();
                if (reader.Read())
                {

                    aux.CodigoEdad = int.Parse(reader["codigoEdad"].ToString());
                    aux.CodigoForraje = int.Parse(reader["codigoForraje"].ToString());
                    if (reader["descripcion"].ToString() != null)
                        aux.Descripcion = reader["descripcion"].ToString();
                    else
                        aux.Descripcion = "";

                    aux.NombreForraje = reader["nombreForraje"].ToString();
                    aux.StockActual = double.Parse(reader["stockActual"].ToString());

                    if (reader["stockMinimo"].ToString() == "")
                        aux.StockMinimo = 0;
                    else
                        aux.StockMinimo = double.Parse(reader["stockMinimo"].ToString());
                    if (reader["stockMaximo"].ToString() == "")
                        aux.StockMaximo = null;
                    else
                        aux.StockMaximo = double.Parse(reader["stockMaximo"].ToString());

                    if (reader["peso"].ToString() == "")
                        aux.Peso = null;
                    else
                        aux.Peso = double.Parse(reader["peso"].ToString());

                    aux.CodigoMarca = int.Parse(reader["CodigoMarca"].ToString());

                    if (reader["estado"].ToString() != null)
                        aux.Estado = reader["estado"].ToString();
                    else
                        aux.Estado = "";
                    if (reader["precioXKilo"].ToString() != "")
                        aux.PrecioXKilo = double.Parse(reader["precioXKilo"].ToString());
                    else
                        aux.PrecioXKilo = 0;
                }
                reader.Close();
                closecon();
                return aux;

            }
            catch (Exception ex)
            {
                reader.Close();
                closecon();
                throw ex;
            }
        }

        public void modificarStock(int codigo, double stock)
        {
            try
            {
                SqlCommand cmd = new SqlCommand("Forraje_UPDATE_Stock", getConexion());
                cmd.CommandType = CommandType.StoredProcedure;

                cmd.Parameters.Add(new SqlParameter("@codigoForraje", codigo));
                cmd.Parameters.Add(new SqlParameter("@stockActual", stock));


                opencon();

                cmd.ExecuteNonQuery();

            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                closecon();
            }

        }


        public DataTable obtenerProductos()
        {
            DataTable dt = new DataTable();

            SqlDataAdapter da = null;


            try
            {
                cmd = new SqlCommand("Producto_GetAll", getConexion());

                cmd.CommandType = CommandType.StoredProcedure;

                opencon();
                da = new SqlDataAdapter(cmd);
                da.Fill(dt);

            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                closecon();

            }

            return dt;



        }
        public int AdicionarConTransaccion(ForrajeMO item)
        {
            item.CodigoForraje = getCodigoInsert("Forraje", "CodigoForraje"); //obtengo el codigo de insercion

            try
            {

                cmd = new SqlCommand(insert, getConexion());
                cmd.CommandType = CommandType.StoredProcedure;


                cmd.Parameters.Add(new SqlParameter("@codigoForraje", item.CodigoForraje));
                cmd.Parameters.Add(new SqlParameter("@descripcion", item.Descripcion));
                cmd.Parameters.Add(new SqlParameter("@nombreForraje", item.NombreForraje));

                cmd.Parameters.Add(new SqlParameter("@stockActual", item.StockActual));
                cmd.Parameters.Add(new SqlParameter("@stockMinimo", item.StockMinimo));


                cmd.Parameters.Add(new SqlParameter("@stockMaximo",  item.StockMaximo));
                cmd.Parameters.Add(new SqlParameter("@codigoEdad",  item.CodigoEdad));
                cmd.Parameters.Add(new SqlParameter("@peso",  item.Peso));
                cmd.Parameters.Add(new SqlParameter("@estado",  item.Estado));
                cmd.Parameters.Add(new SqlParameter("@codigoMarca", item.CodigoMarca));
                cmd.Parameters.Add(new SqlParameter("@precioXKilo",  item.PrecioXKilo));
                opencon(); //abro conexion
                cmd.ExecuteNonQuery();
                closecon();

                return item.CodigoForraje;
            }
            catch (SqlException ex)
            {

                closecon();
                throw ex;
            }
        }

        public void ActualizarConTransaccion(ForrajeMO nuevoItem, ForrajeMO origItem)
        {
            try
            {
                cmd = new SqlCommand(update, getConexion());
                cmd.CommandType = CommandType.StoredProcedure;



                cmd.Parameters.Add(new SqlParameter("@codigoForraje", origItem.CodigoForraje));
                cmd.Parameters.Add(new SqlParameter("@descripcion", nuevoItem.Descripcion));
                cmd.Parameters.Add(new SqlParameter("@nombreForraje",  nuevoItem.NombreForraje));

                cmd.Parameters.Add(new SqlParameter("@stockActual",  nuevoItem.StockActual));
                cmd.Parameters.Add(new SqlParameter("@stockMinimo",  nuevoItem.StockMinimo));


                cmd.Parameters.Add(new SqlParameter("@stockMaximo",  nuevoItem.StockMaximo));
                cmd.Parameters.Add(new SqlParameter("@codigoEdad",  nuevoItem.CodigoEdad));
                cmd.Parameters.Add(new SqlParameter("@peso", nuevoItem.Peso));
                cmd.Parameters.Add(new SqlParameter("@estado", nuevoItem.Estado));
                cmd.Parameters.Add(new SqlParameter("@codigoMarca",nuevoItem.CodigoMarca));
                cmd.Parameters.Add(new SqlParameter("@precioXKilo", nuevoItem.PrecioXKilo));

                opencon(); //abro conexion
                cmd.ExecuteNonQuery();
                closecon(); //cierra conexion


            }
            catch (SqlException ex)
            {
                closecon();
                throw ex;
            }
        }

        public List<AnimalMO> getDetalle(int id)
        {
            List<AnimalMO> lista = new List<AnimalMO>();
            SqlDataReader reader = null;
            try
            {
                cmd = new SqlCommand(detalle, getConexion());
                cmd.CommandType = CommandType.StoredProcedure;

                cmd.Parameters.Add(new SqlParameter("@id_forraje",id));
                opencon();

                reader = cmd.ExecuteReader();
                while (reader.Read())
                {

                    AnimalMO aux = new AnimalMO();

                    //**************************************Formacion del objeto aux ******************************************************************
                    aux.CodigoAnimal = int.Parse(reader["Codigo"].ToString());
                    aux.Nombre = reader["Nombre"].ToString();
                    //********************************** fin Formacion objeto aux **********************************************************************

                    lista.Add(aux);
                    aux = null;
                }
                return lista;
            }
            catch (Exception ex)
            {
                throw ex; //en caso que no pueda leer desde la base de datos tira el hacia la siguiente capa 
            }
           finally //finalmente cierro el reader que use para traer la consulta esto es importante ya que por alguna razon podria quedar abierto generando una conexion sin uso en la bd que estaria todo el tiempo abierta
            {
                closeReader(reader); //cierro el reader
                closecon();// cierra conexion

            }


        }

        public DataTable reporteForrajeStock(string forraje = "", double stock = 0, bool minimo = false, string ordena = "", string dire = "")
        {
            string sql = "";
            sql = "SELECT f.codigoForraje as 'Codigo_Forraje',f.nombreForraje as 'Nombre_Forraje',f.descripcion as 'Descripcion',f.stockMinimo as 'Stock_Minimo',f.stockActual as 'Stock_Actual',f.stockMaximo as 'Stock_Maximo',f.precioXKilo as 'Precio/Kilo', m.nombre as 'Marca', e.descripcion as 'Edad' "
                + " FROM Forraje f left join Marca m ON f.codigoMarca = m.codigoMarca left join Edades e on f.codigoEdad = e.codigoEdad WHERE f.estado = 'A' ";

            try
            {
                DataTable dt = new DataTable();

                SqlCommand cmd = new SqlCommand();

                if (forraje != "")
                {

                    sql += " and  f.nombreForraje like @forra+'%'";
                    cmd.Parameters.Add(new SqlParameter("@forra",  forraje));
                }

                if (minimo == false)
                {
                    if (stock != 0)
                    {
                        sql += " and  f.stockActual = @stock";
                        cmd.Parameters.Add(new SqlParameter("@stock",  stock));
                    }
                }
                else
                {
                    sql += " and f.stockActual <= f.stockMinimo";
                }
                if (ordena != "")
                {

                    sql += " Order by " + ordena;

                }
                if (dire != "")
                    sql += " " + dire;


                cmd.Connection = (getConexion());

                cmd.CommandText = sql;
                cmd.CommandType = CommandType.Text;
                SqlDataAdapter da = new SqlDataAdapter(cmd);

                opencon();
                da.Fill(dt);
                closecon();
                return dt;
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                closecon();
            }
        }


        public DataTable buscarForrajes(string nombre, string edad, string marca, string animal)
        {
            DataTable dt = new DataTable();

            SqlDataAdapter da = null;

            
            string sql = null;

            sql+=   "SELECT f.codigoForraje as codigoForraje, f.nombreForraje AS nombre,";
            sql += " m.Nombre as marca,";
            sql += " e.descripcion as edad, ";
            sql += " a.nombre as animal,";
            sql += " a.codigoAnimal as codigoAnimal,";
            sql += " f.stockActual as stock,";
            sql += " f.precioXKilo as precio,";
            sql += " f.peso as peso,";
            sql += " f.descripcion as descripcionForraje,";
            sql += " f.stockMinimo as stockMinimo,";
            sql += " f.stockMaximo as stockMaximo,";
            sql += " f.codigoEdad as codigoEdad,";
            sql += " f.codigoMarca as codigoMarca";
            sql += " FROM Forraje f INNER JOIN Edades e ON f.codigoEdad=e.codigoEdad";
            sql += " INNER JOIN Marca m ON f.codigoMarca=m.codigoMarca";
            sql += " INNER JOIN AnimalXForraje af ON f.codigoForraje=af.codigoForraje";
            sql += " INNER JOIN Animal a ON af.codigoAnimal=a.codigoAnimal";
            sql += " WHERE f.estado='A'";


            try
            {
                cmd = null;

                List<SqlParameter> param = new List<SqlParameter>();

                if (!String.IsNullOrWhiteSpace(nombre))
                {
                    //where = true;
                    sql += " AND f.nombreForraje=@nombre";
                    param.Add(new SqlParameter("@nombre", nombre));
                }

                if (!String.IsNullOrWhiteSpace(edad))
                {
                    sql += " AND f.codigoEdad=@edad";
                   
                    param.Add(new SqlParameter("@edad", edad));
                }

                if (!String.IsNullOrWhiteSpace(marca))
                {
                    sql += " AND f.codigoMarca=@marca";
                    
                    param.Add(new SqlParameter("@marca", marca));
                }

                if (!String.IsNullOrWhiteSpace(animal))
                {
                    sql += " AND a.codigoAnimal=@animal";
                 
                    param.Add(new SqlParameter("@animal", animal));
                }

                cmd = new SqlCommand(sql, getConexion());
                cmd.CommandType = CommandType.Text;
                cmd.Parameters.AddRange(param.ToArray());

                opencon();
                da = new SqlDataAdapter(cmd);


                da.Fill(dt);

            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                closecon();

            }

            return dt;


        }
        public DataTable getInformeForrajes(int? codAnimal, float? stockActual, string estado)
        {
            DataTable dt = new DataTable();

            SqlDataAdapter da = null;

            string sql = "select Forraje.codigoForraje as CodigoForraje, Forraje.nombreForraje as NombreForraje, Forraje.stockActual as StockActual, Forraje.peso as Peso, Forraje.precioXKilo as Precio, Forraje.stockMinimo AS StockMinimo, Forraje.stockMaximo as StockMaximo, Forraje.estado as Estado, Animal.nombre as NombreAnimal, Marca.Nombre as NombreMarca from Forraje, AnimalXForraje, Animal, Marca where Forraje.codigoForraje=AnimalXForraje.codigoForraje AND AnimalXForraje.codigoAnimal=Animal.codigoAnimal AND Forraje.codigoMarca=Marca.codigoMarca";

            try
            {
                cmd = new SqlCommand(sql, getConexion());
                if (stockActual != null)
                {
                    sql += " AND Forraje.stockActual>=@stockActual";
                    cmd.Parameters.AddWithValue("@stockActual", stockActual.Value);
                }
                if (codAnimal != null)
                {
                    sql += " AND Animal.codigoAnimal=@codiogAnimal";
                    cmd.Parameters.AddWithValue("@codiogAnimal", codAnimal.Value);
                }
                if (estado != null)
                {
                    sql += " AND Forraje.estado=@estado";
                    cmd.Parameters.AddWithValue("@estado", estado);
                }


                cmd.CommandType = CommandType.Text;
                cmd.CommandText = sql;

                opencon();
                da = new SqlDataAdapter(cmd);


                da.Fill(dt);
            }
            catch (Exception ex)
            {

                throw ex;
            }
            finally
            {
                closecon();

            }

            return dt;
        }

    }
}
